#ifndef AGENTW_SNLP
#define AGENTW_SNLP

#include "Pair.h"


class SNLPCausalLink {
public:
    SNLPCausalLink() {
        op1 = 0;
        op2 = 0;
        condition = 0;
    }
    ~SNLPCausalLink() {
        if (op1!=0) delete op1;
        if (op2!=0) delete op2;
        if (condition!=0) delete condition;
    }
	FeatureTerm *op1,*op2,*condition;
};

class SNLPThreat {
public:
    SNLPThreat() {
        l = 0;
        op = 0;
        condition = 0;
    }
    ~SNLPThreat() {
    }
	SNLPCausalLink *l;
    FeatureTerm *op,*condition;
};



class SNLPState {
public:
	List<Pair<FeatureTerm,FeatureTerm> > open_conditions;	// List of unsatisfied conditions of any operator(or final state) <Condition,Operator>
	List<FeatureTerm> operators;
	List<SNLPCausalLink> causal_links;
	List<Pair<FeatureTerm,FeatureTerm> > separation_constraints;
	
	List<FeatureTerm> *get_linearization(void);
	bool operator_before(FeatureTerm *op1,FeatureTerm *op2);	
	SNLPState *clone_adding(FeatureTerm *op2,FTKBase *dm,List<FeatureTerm> *old_n,List<FeatureTerm> *new_n);
    
    void addCausalLink(SNLPState *oldState,FeatureTerm *oldOp,FeatureTerm *oldCondition);
    void removeCondition(SNLPState *oldState,FeatureTerm *oldCondition);
    bool canUnify(FeatureTerm *g1, FeatureTerm *g2);
    
    void printStateNice(FTKBase *dm);
};

List<FeatureTerm> *SNLP_dfs(FeatureTerm *initialState,FeatureTerm *goalState,FTKBase *domain_model,Ontology *o);
List<FeatureTerm> *SNLP_bfs(FeatureTerm *initialState,FeatureTerm *goalState,FTKBase *domain_model,Ontology *o);
List<FeatureTerm> *SNLP_h(FeatureTerm *initialState,FeatureTerm *goalState,FTKBase *domain_model,Ontology *o);

#endif
